using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Windows.Forms;
using RdfMusic;
using RdfSerialisation;
using SemWeb;
using SemWeb.Query;

namespace Mp3ToRdf
{
    public partial class SearchResults : Form
    {
        public IList<Track> TracksFound
        {
            get { return tracksFound; }
            set { tracksFound = value; }
        }

        public IList<Track> tracksFound;

        private IList<string> genres;
        private IList<string> artists;
        private IList<string> years;
        private MusicStore store;

        public IList<string> Artists
        {
            get { return artists; }
            set { artists = value; }
        }

        public IList<string> Years
        {
            get { return years; }
            set { years = value; }
        }

        public IList<string> Genres
        {
            get { return genres; }
            set { genres = value; }
        }

        public MusicStore Store
        {
            get { return store; }
            set { store = value; }
        }

        public SearchResults()
        {
            InitializeComponent();
        }

        private void SearchResults_Load(object sender, System.EventArgs e)
        {
            if (!SufficientDataToSearch())
            {
                DisplayErrorMessage();
                return;
            }
            IList<Track> result = DoSearch();
            DisplayResults(result);
        }

        private void DisplayResults(IList<Track> result)
        {
            this.dataGridView1.DataSource = tracksFound;
        }

        private IList<Track> DoSearch()
        {
            MemoryStore ms = Store.TripleStore;
			ObjectDeserialiserQuerySink sink = new ObjectDeserialiserQuerySink(typeof(Track), typeof(Track));
            string qry = CreateQueryForArtist(artists[0].Trim());
            Query query = new GraphMatch(new N3Reader(new StringReader(qry)));
            query.Run(ms, sink);

            return tracksFound = sink.DeserialisedObjects as IList<Track>;
        }

        private static string CreateQueryForArtist(string artistName)
        {
            string queryFmt = "@prefix m: <http://aabs.purl.org/ontologies/2007/04/music#> .\n";
            foreach (PropertyInfo info in OwlClassSupertype.GetAllPersistentProperties(typeof(Track)))
            {
                queryFmt += string.Format("?track <{0}> ?{1} .\n", OwlClassSupertype.GetPropertyUri(typeof(Track), info.Name), info.Name);
            }
            queryFmt += string.Format("?track <{0}> \"{1}\" .\n", OwlClassSupertype.GetPropertyUri(typeof(Track), "ArtistName"), artistName);
            return queryFmt;
        }

        private void DisplayErrorMessage()
        {
            MessageBox.Show("You didn't provide enough information for a track search to be performed.", "Error",
                            MessageBoxButtons.OK, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button1,
                            MessageBoxOptions.ServiceNotification);
        }

        private bool SufficientDataToSearch()
        {
            return (Store != null && Store.TripleStore != null);
        }
        bool StringEmpty(string s)
        {
            return (s == null || s.Length == 0);
        }
    }
}